home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / Vollversion / CamD / development / examples / drum / timer.a < prev    next >
Text File  |  2000-05-15  |  7KB  |  192 lines

  1. ;* ============================================================================ *
  2. ;                          Deluxe Music Construction Set II
  3. ;                          timer.asm -- CIA timer interrupt
  4. ;                                     By Talin.
  5. ;* ============================================================================ */
  6.  
  7.             include     "exec/types.i"
  8.             include     "exec/tasks.i"
  9.             include     "dos/dos.i"
  10.             include     "libraries/realtime.i"
  11.  
  12.             xdef        _TimeServer
  13.             xdef        _CalcClockIncrement
  14.  
  15.             xref        _tempo_rate
  16.             xref        _mclock_pos
  17.             xref        _mclock_accumulator
  18.             xref        _mclocks_per_column
  19.             xref        _pattern_mclocks
  20.             xref        _current_pattern_start
  21.             xref        _current_pattern_end
  22.             xref        _pattern_pos
  23.             xref        _column_pos
  24.             xref        _clock_pos
  25.             xref        _main_task
  26.             xref        _clock_state
  27.  
  28.             xref        _SysBase
  29.             xref        _LVOSignal
  30.  
  31.             SECTION     text,CODE
  32.  
  33. _TimeServer
  34.             move.l      pmt_Method(a1),d0       ; d0 <-- method id
  35.             cmp.l       #PM_TICK,d0             ; is it a tick message?
  36.             bne         10$
  37.  
  38. ;---------- determine the number of ticks which have occured since
  39. ;           the last time this hook was called.
  40.  
  41.             move.l      pmt_Time(a1),d0         ; d0 <-- current clock time
  42.             bmi         2$                      ; DMCS doesn't deal with negative time...
  43.             move.l      _clock_pos,d1           ; d1 <-- time of last call
  44.             sub.l       d1,d0                   ; d0 <-- time since last call
  45.             bmi         2$                      ; if clock went backwards, ignore...
  46.             add.l       d0,_clock_pos           ; update accumulated time
  47.  
  48. ;---------- Check to see if we're the Maestro
  49.  
  50. *           move.l      pl_Source(a2),a0        ; a0 <-- Conductor
  51. *           btst.b      #CONDUCTB_METROSET,cdt_Flags+1(a0) ; if metronome already set
  52. *           beq.s       1$
  53. *           move.l      cdt_Metronome(a0),d0    ; d0 <-- current metronome time
  54. *           move.l      d0,pl_MetricTime(a2)    ; update playerinfo w/ time
  55. *           bra.s       4$
  56.  
  57. ; d0 now equals the number of ticks since the last time we updated _clock_pos.
  58. ; use this to do an extended precision multiply...
  59.  
  60.             move.l      d0,d1                   ; get copy of delta time
  61.             swap        d1                      ; get upper half
  62.             mulu.w      _tempo_rate,d1          ; do extended precision math.
  63.             swap        d1                      ; put extended part in upper
  64.             clr.w       d1                      ; half of d1
  65.  
  66.             mulu.w      _tempo_rate,d0          ; d0 <-- musical ticks since last
  67.             add.l       d1,d0                   ; add extended precision part.
  68.  
  69. ; d0 has now been converted to a delta-mclocks * 256
  70.  
  71.             add.l       _mclock_accumulator,d0  ; d0 <-- total elapsed musical time
  72.             move.l      d0,_mclock_accumulator  ; update tempo_accumulator
  73.  
  74. ; d0 now contains to total elapsed mclocks.
  75.  
  76.             asr.l       #8,d0                   ; convert fixed-point to integer
  77.  
  78. ;---------- since we're musically aware, update the "conducted" bit.
  79.  
  80. ;           move.l      d0,cdt_Metronome(a0)    ; update conductor metronome
  81. ;           bset.b      #CONDUCTB_METROSET,cdt_Flags+1(a0) ; set metronome flag
  82.  
  83.             cmp.l       pl_MetricTime(a2),d0    ; see if they are the same
  84.             beq.s       2$                      ; no point in waking up if they are.
  85.  
  86. 4$          move.l      d0,pl_MetricTime(a2)    ; see if they are the same
  87.  
  88. ;---------- See if we overflowed into the next pattern
  89.  
  90. 5$          cmp.l       _current_pattern_end,d0 ; see if we're at the frame end
  91.             blt.s       6$
  92.  
  93.             add.l       #1,_pattern_pos         ; add 1 to pattern position
  94.                                                 ; new start <-- old end
  95.             move.l      _current_pattern_end,_current_pattern_start
  96.                                                 ; new end += pattern size
  97.             move.l      _pattern_mclocks,d1
  98.             add.l       d1,_current_pattern_end
  99.             bra.s       5$
  100.  
  101. ;---------- calculate the column # within the pattern
  102.  
  103. 6$          sub.l       _current_pattern_start,d0   ; clocks in this pattern
  104.             divu        _mclocks_per_column,d0  ; get column #
  105.  
  106.             cmp.w       _column_pos,d0          ; see if column # changed
  107.             beq.s       2$                      ; if so
  108.  
  109.             move.w      d0,_column_pos          ; then update column # and signal
  110.  
  111. ;---------- get ExecBase into a6.
  112.  
  113.             move.l      a6,-(sp)
  114.             move.l      _SysBase,a6
  115.  
  116. ;---------- signal main task that a state change has occurred
  117.  
  118.             move.l      _main_task,a1           ; address of player task
  119.             move.l      #SIGBREAKF_CTRL_F,d0    ; signal to send
  120.             CALLLIB     _LVOSignal              ; wake up player task
  121.  
  122. ;---------- restore a6 register
  123.  
  124.             move.l      (sp)+,a6
  125.  
  126. ;---------- just exit
  127.  
  128. 2$          moveq       #0,d0
  129.             rts
  130.  
  131. 10$         cmp.l       #PM_STATE,d0            ; is it a state-change message?
  132.             bne.s       20$
  133.  
  134. ;---------- get ExecBase into a6.
  135.  
  136.             move.l      a6,-(sp)
  137.             move.l      _SysBase,a6
  138.  
  139. ;---------- signal main task that a state change has occurred
  140.  
  141.             move.l      _main_task,a1           ; address of player task
  142.             move.l      #SIGBREAKF_CTRL_E,d0    ; signal to send
  143.             CALLLIB     _LVOSignal              ; wake up player task
  144.  
  145. ;---------- restore a6 register
  146.  
  147.             move.l      (sp)+,a6
  148.  
  149. ;---------- return from hook
  150.  
  151.             moveq       #0,d0                   ; end server chain???
  152.             rts
  153.  
  154. 20$
  155. ;           cmp.l       #PM_POSITION,d0         ; is it a special locate?
  156. ;           bne.s       30$
  157. ;
  158. ;;---------- handle special locate message
  159. ;
  160. ;           move.l      pmt_Time(a1),_special_locate_time
  161. ;
  162. ;           move.l      a6,-(sp)
  163. ;           move.l      _SysBase,a6
  164. ;
  165. ;;---------- signal player task that a state change has occurred
  166. ;
  167. ;           move.l      _player_task,a1         ; address of player task
  168. ;           move.l      #SIGF_INTUITION,d0      ; signal to send
  169. ;           Call        Signal                  ; wake up player task
  170. ;
  171. ;;---------- restore a6 register
  172. ;
  173. ;           move.l      (sp)+,a6
  174.  
  175. ;---------- return from hook
  176.  
  177. 30$         moveq       #0,d0                   ; end server chain???
  178.             rts
  179.  
  180. _CalcClockIncrement         ; (music delta)
  181. ;           move.l      4(sp),d0                ; d0 <-- musical ticks
  182. ;           lsl.l       #8,d0                   ; d0 <-- musical ticks * 256
  183. ;           add.l       _time_remainder,d0      ; plus remaining ticks
  184. ;           divu.w      _tempo_rate+2,d0        ; d0.w <-- real-time ticks
  185. ;           swap.w      d0                      ; get remainder
  186. ;           move.w      d0,_time_remainder+2    ; put remainder into time remainder
  187. ;           clr.w       d0                      ; clear lower half d0
  188. ;           swap.w      d0                      ; d0.l <--real-time ticks
  189. ;           rts
  190.  
  191.             end
  192.